package com.iot.gateway.tsl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.iot.gateway.tsl.mapper.TslEventAttrMapper;
import com.iot.gateway.tsl.mapper.TslEventMapper;
import com.iot.gateway.tsl.model.TslEventAttrEntity;
import com.iot.gateway.tsl.model.TslEventEntity;
import com.iot.gateway.tsl.qo.DataTypeQo;
import com.iot.gateway.tsl.qo.EventOutputParamQo;
import com.iot.gateway.tsl.qo.EventQo;
import com.iot.gateway.tsl.service.TslEventService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 物模型管理 - 事件管理实现
 *
 * @author guoxinyu
 * @create 2025/5/27 18:35
 */
@Service
public class TslEventServiceImpl implements TslEventService {

    private final TslEventMapper eventMapper;
    private final TslEventAttrMapper attrMapper;

    public TslEventServiceImpl(TslEventMapper eventMapper,
                               TslEventAttrMapper attrMapper) {
        this.eventMapper = eventMapper;
        this.attrMapper = attrMapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addEvent(String deviceId, EventQo eventQo) {
        // 1. 插入固定字段
        TslEventEntity entity = new TslEventEntity();
        entity.setEventId(Optional.ofNullable(eventQo.getId())
                .filter(id -> !id.isEmpty())
                .orElse(UUID.randomUUID().toString()));
        entity.setDeviceId(deviceId);
        entity.setName(eventQo.getName());
        entity.setDescription(eventQo.getDescription());
        entity.setType(eventQo.getType());
        entity.setRequired(Boolean.TRUE.equals(eventQo.getRequired()));
        // Map EventOutputParamQo → List<Map<String,Object>>
        if (eventQo.getOutputData() != null) {
            List<Map<String, Object>> outputData = eventQo.getOutputData().stream().map(p -> {
                Map<String, Object> m = new HashMap<>();
                m.put("pid", p.getPid());
                m.put("name", p.getName());
                m.put("dataType", p.getDataType());
                m.put("customFields", p.getCustomFields());
                return m;
            }).collect(Collectors.toList());
            entity.setOutputData(outputData);
        }
        eventMapper.insert(entity);

        // 2. 插入动态扩展字段
        if (eventQo.getCustomFields() != null) {
            List<TslEventAttrEntity> attrs = eventQo.getCustomFields().entrySet().stream()
                    .map(e -> {
                        TslEventAttrEntity a = new TslEventAttrEntity();
                        a.setEventId(entity.getEventId());
                        a.setAttrKey(e.getKey());
                        a.setAttrValue(Objects.toString(e.getValue(), null));
                        return a;
                    })
                    .collect(Collectors.toList());
            attrs.forEach(attrMapper::insert);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEvent(String deviceId, EventQo eventQo) {
        // 1. 更新固定字段
        TslEventEntity entity = new TslEventEntity();
        entity.setEventId(eventQo.getId());
        entity.setDeviceId(deviceId);
        entity.setName(eventQo.getName());
        entity.setDescription(eventQo.getDescription());
        entity.setType(eventQo.getType());
        entity.setRequired(Boolean.TRUE.equals(eventQo.getRequired()));
        if (eventQo.getOutputData() != null) {
            List<Map<String, Object>> outputData = eventQo.getOutputData().stream().map(p -> {
                Map<String, Object> m = new HashMap<>();
                m.put("pid", p.getPid());
                m.put("name", p.getName());
                m.put("dataType", p.getDataType());
                m.put("customFields", p.getCustomFields());
                return m;
            }).collect(Collectors.toList());
            entity.setOutputData(outputData);
        }
        eventMapper.updateById(entity);

        // 2. 重建动态扩展字段：先删后插
        attrMapper.delete(new LambdaQueryWrapper<TslEventAttrEntity>()
                .eq(TslEventAttrEntity::getEventId, eventQo.getId()));

        if (eventQo.getCustomFields() != null) {
            eventQo.getCustomFields().forEach((k, v) -> {
                TslEventAttrEntity a = new TslEventAttrEntity();
                a.setEventId(eventQo.getId());
                a.setAttrKey(k);
                a.setAttrValue(Objects.toString(v, null));
                attrMapper.insert(a);
            });
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteEvent(String deviceId, String eventId) {
        // 删除动态扩展字段
        attrMapper.delete(new LambdaQueryWrapper<TslEventAttrEntity>()
                .eq(TslEventAttrEntity::getEventId, eventId));
        // 删除固定字段
        eventMapper.deleteById(eventId);
    }

    @Override
    public List<EventQo> getEvents(String deviceId) {
        // 查询固定字段
        List<TslEventEntity> entities = eventMapper.selectList(
                new LambdaQueryWrapper<TslEventEntity>()
                        .eq(TslEventEntity::getDeviceId, deviceId)
        );

        // 批量查询扩展字段
        List<String> ids = entities.stream()
                .map(TslEventEntity::getEventId)
                .collect(Collectors.toList());
        List<TslEventAttrEntity> allAttrs = attrMapper.selectList(
                new LambdaQueryWrapper<TslEventAttrEntity>()
                        .in(TslEventAttrEntity::getEventId, ids)
        );
        Map<String, List<TslEventAttrEntity>> grouped = allAttrs.stream()
                .collect(Collectors.groupingBy(TslEventAttrEntity::getEventId));

        // 组装 DTO
        return entities.stream().map(e -> {
            EventQo qo = new EventQo();
            qo.setId(e.getEventId());
            qo.setName(e.getName());
            qo.setDescription(e.getDescription());
            qo.setType(e.getType());
            qo.setRequired(e.getRequired());

            // outputData: List<Map<String,Object>> → List<EventOutputParamQo>
            if (e.getOutputData() != null) {
                List<EventOutputParamQo> outputParams = e.getOutputData().stream().map(m -> {
                    EventOutputParamQo p = new EventOutputParamQo();
                    p.setPid((String) m.get("pid"));
                    p.setName((String) m.get("name"));
                    @SuppressWarnings("unchecked")
                    Map<String,Object> dtMap = (Map<String,Object>) m.get("dataType");
                    DataTypeQo dt = new DataTypeQo();
                    dt.setType((String) dtMap.get("type"));
                    dt.setSpecs((Map<String,Object>) dtMap.get("specs"));
                    p.setDataType(dt);
                    @SuppressWarnings("unchecked")
                    Map<String,Object> cf = (Map<String,Object>) m.get("customFields");
                    p.setCustomFields(cf);
                    return p;
                }).collect(Collectors.toList());
                qo.setOutputData(outputParams);
            }

            // 自定义扩展字段
            Map<String, Object> custom = new HashMap<>();
            List<TslEventAttrEntity> attrs = grouped.get(e.getEventId());
            if (attrs != null) {
                attrs.forEach(a -> custom.put(a.getAttrKey(), a.getAttrValue()));
            }
            qo.setCustomFields(custom);

            return qo;
        }).collect(Collectors.toList());
    }
}
